#!/usr/bin/env python
#-*- coding:utf8 -*-
"""
Function attributes:
* load: boolean. Optional. If False the function will not load.
* name: string. Optional.
* priority: string. Optional. Three values are available: "high", "medium" or "low",
  default value: "medium".
* thread: boolean. Optional. If True, function will work by starting a thread.
* rule: string or regexp object. Required.
* aliases: list of string or regexp objects. Optional.
* fullmsg: boolean. Optional. If True, pattern is searched on whole message, else
  pattern is a command, the message must begin with a sign.

* access
* evttypes: must be tuple
* skip_sentinel: skip _sentinel instance
* limit
* channels
* url
* showas
"""
import re, json, codecs as cs, time
from datetime import datetime
from dateutil.relativedelta import relativedelta as time_diff
from util.pywikilib import Site, Page, WikiLink, Time
from core.ircfuncs import has_access
from util.functions import wikiquote, urlencode, encode, decode, format_number, join_list
from core.optimizers import fmt, File
from util.sitematrix import families
field = "site"

def get_sitematrix(site):
	data = site.get_api({"action": "sitematrix"})['sitematrix']
	sitematrix = {}
	for site in data:
		if site.isdigit():
			print data[site]
			sitematrix[data[site]['code']] = {"localname": data[site].has_key('localname') and data[site]['localname'], "ownname": data[site]['name'], "families": [x['code'] if x['code'] != "wiki" else "wikipedia" for x in data[site]['site']]}
	return sitematrix

def wname(bot, evt, cmd):
	lang = cmd.arguments
	filename = "sitematrix_%s.log" % evt.lang
	site = Site(evt.lang, evt.fam)
	f = File(filename)
	if f.exists():
		sitematrix = f.get()
	else:
		sitematrix = get_sitematrix(site)
		f.put(sitematrix)
		#json.dump(sitematrix, cs.open("sitematrix_%s.log" % lang,"w","utf8"), indent=2)

	#edit sitematrix file
	if has_access(bot, "support", evt) and cmd.action:
		if cmd.action == "edit":
			chg=False
			if cmd.opts['ln'] and sitematrix[lang]['localname']!= cmd.opts:
				sitematrix[lang]['localname'] = cmd.opts['ln']
				chg=True
			if cmd.opts['on'] and sitematrix[lang]['ownname'] != cmd.opts['on']:
				sitematrix[lang]['ownname'] = cmd.opts['on']
				chg = True
			if chg:
				f.put(sitematrix,True)
				bot.reply(evt, "data modified successfully")
		elif cmd.action == "update":
			updated_sm = get_sitematrix(site)
			l=0; f={}
			for lng in updated_sm:
				if lng not in sitematrix:
					sitematrix.update({lng: updated_sm[lng]})
					l+=1
				if updated_sm[lng]['families'] != sitematrix[lng]['families']:
					f.update({lng: len(updated_sm[lng]['families'])-len(sitematrix[lng]['families'])})
					sitematrix[lng]['families']= updated_sm[lng]['families']
			if l or f:
				msg=""
				if l: msg += "%i more languages founded." % l
				if f: msg += ", ".join(["%s has %i families more" %(k,v) for k,v in f.iteritems()])
				bot.reply(evt, msg)
		return True

	#get match
	langnames = dict([(sitematrix[code]['localname'].lower(), code) for code in sitematrix if sitematrix[code]['localname']])
	langnames.update(dict([(sitematrix[code]['ownname'].lower(), code) for code in sitematrix if sitematrix[code]['ownname']]))
	if evt.lang == "ca":
		lang = lang.replace(u"é", u"è")
		lang = lang.replace(u"valencià", u"català")
		lang = lang.replace(u"español", u"castellà")
		lang = lang.replace(u"espanyol", u"castellà")
	if sitematrix.has_key(lang):
		bot.reply (u"Projects in %s language (local name: %s). This language has %i projects (%s).",
			sitematrix[lang]['localname'],
			sitematrix[lang]['ownname'],
			len(sitematrix[lang]['families']),
			", ".join(sitematrix[lang]['families'])
		)
	elif lang.lower() in langnames:
		code = langnames[lang.lower()]
		bot.reply (u"Projects in %s language (local name: %s, code: %s). This language has %i projects (%s).",
			sitematrix[code]['localname'],
			sitematrix[code]['ownname'],
			code,
			len(sitematrix[code]['families']),
			", ".join(sitematrix[code]['families'])
		)
	else:
		bot.reply(evt, "This is not a language code.")
wname.rule = "wname"

ranking_positions={}
def get_ranktable(wlink):
	family = wlink.family()
	tables = {
		"wikipedia": ("Table of Wikipedias.txt", "List of Wikipedias/Table"),
		"wiktionary": ("Table of Wiktionaries.txt", "Wiktionary/Table"),
		"wikisource": ("Table of Wikisources.txt", "Wikisource/Table"),
		"wikinews": ("Table of Wikinews.txt", "Wikinews/Table"),
		"wikiquote": ("Table of Wikiquotes.txt", "Wikiquote/Table"),
		"wikibooks": ("Table of Wikibooks.txt", "Wikibooks/Table"),
		"wikiversity": ("Table of Wikiversities.txt", "Wikiversity/Table")
	}
	fname = tables[family][0]
	f = File(fname)
	file_is_deprecated = (Time(time.time()).obj - Time(f.modified()).obj).days > 0 if f.exists() else False
	write = True if not f.exists() or file_is_deprecated else False
	if write:
		text = Page(Site("meta"), tables[family][1]).content()
		f.put(text, True)
		f.close()
	else:
		text=f.get()
		f.close()
	restr = {
		"wikipedia": r"""\|-
\| (?P<pos>\d+)
\| \[\[w:[^|]+\|(?P<English>[^\]]+)\]\]\s*
\| class="plainlinksneverexpand" \| \[\{\{fullurl:[^}]+\}\} (?P<local>[^\]]+)\]
\| \[\[:(?P<code>[\w-]+):\|[^\]]+\]\]
\| class="plainlinksneverexpand" \| \[\{\{fullurl:[^}]+\}\} '{3}(?P<articles>[\d,]+)'{3}</span>\]

\| (?#total)[\d,]+
\| \[\[:[\w-]+:Special:Statistics\|[\d,]+\]\]
\| \[\[:[\w-]+:Special:Listadmins\|[\d,]+\]\]
\| \[\[:[\w-]+:Special:Listusers\|[\d,]+\]\]
\| \[\[:[\w-]+:Special:ActiveUsers\|[\d,]+\]\]
\| \[\[:[\w-]+:Special:Imagelist\|[\d,]+\]\]
\| [\d,-]+""", #15.04.13

	"wikisite": r"""\|- style="text-align: right;"
\| (?P<pos>\d+)
\| \[\[w:[^|]+\|(?P<English>[^\]]+)\]\]
\| \[\[w:[^|]+\|(?P<local>[^\]]+)\]\]
\| \[[^ ]+ (?P<code>[^\]]+)\]
\| \[[^ ]+ '{3}(?P<articles>\d+)'{3}\]
\| (?#total)\d+
\| \[[^ ]+?/Special:Recentchanges \d+\]
\| \[[^ ]+?/Special:Listadmins \d+\]([]\r\n\s]+\| \[[^ ]+?/Special:ActiveUsers \d+\])??
\| \[[^ ]+?/Special:Listusers \d+\]([]\r\n\s]+\| \[[^ ]+?/Special:ActiveUsers \d+\])??
\| \[[^ ]+?/Special:Imagelist \d+\][\r\n\s]*?
\| style="font-size: 70%;[^"]*" \| [\d:\- ]+""", #30.04.2012
	"wikibook": """|- style="text-align: right;"
| 1
| [[w:English language|English]]
| [[w:English language|English]]
| [http://en.wikiversity.org/wiki/ en]
| [http://en.wikiversity.org/wiki/Special:Statistics?action=raw '''18144''']
| 112234
| [http://en.wikiversity.org/wiki/Special:Recentchanges 923222]
| [http://en.wikiversity.org/wiki/Special:Listadmins 29]
| [http://en.wikiversity.org/wiki/Special:ActiveUsers 448305]
| [http://en.wikisource.org/wiki/Special:Listusers 421]
| [http://en.wikiversity.org/wiki/Special:Imagelist 12734]
| style="font-size: 70%; white-space:nowrap" | 2012-04-18 13:00:02
"""
	}
	wiki = restr.has_key(family) and "wikipedia" or "wikisite"
	projs = re.findall(restr[wiki], text, re.S | re.M)
	sm={}
	print time.strftime("%H:%M:%S"), "PROJS:", len(projs), family, wiki
	for proj in projs:
		sm[proj[3]] = (proj[1], proj[2], proj[0], proj[4])
		ranking_positions[proj[0]] = proj[3]
	if sm.has_key("ca"): print sm["ca"]
	return sm, tables[family][1]

def ranking(args, wlink):
	sm, metalink = get_ranktable(wlink)
	ranking = {}
	for k,v in ranking_positions.items():
		ranking[v] = k
	msg = ""
	proj = args.split(":")[-1] or wlink.language()
	if proj.isdigit():
		proj = int(proj)
		rp = {}
		for k, v in sm.iteritems():
			rp[int(v[2])] = (v[0],v[1], k, v[3])

		if proj > len(sm) or proj < 0:
			return "Choose a number between 1 and %i" %len(sm)
		else:
			before = proj - 1
			after = proj + 1
			articles1 = articles2 = articles3 = 0
			if before > 0:
				wikibefore = rp.get(before)[2]
				site = Site(wikibefore, wlink.family())
				articles1 = site.get_articles()
				msg += u"&t;%i&N;. &B;%s&N; %s" % (before, wikibefore, format_number(articles1,0))
			wikimiddle = rp.get(proj)[2]
			site = Site(wikimiddle, wlink.family())
			articles2 = site.get_articles()
			diff = format_number(articles1 - articles2, 0) if articles1 else ""
			diff = u" (+%s) | " % diff if diff else "" if not diff and not msg else u" | "
			msg += u"%s&t;%i&N;. &B;%s&N; %s" % (diff, proj, wikimiddle, format_number(articles2,0))
			if after <= len(rp):
				wikiafter=rp.get(after)[2]
				site = Site(wikiafter, wlink.family())
				articles3 = site.get_articles()
				diff = format_number(articles2 - articles3, 0)
				diff = u" (-%s)" % diff if diff else ""
				msg += u" | &t;%i&N;. &B;%s&N; %s%s" %(after, wikiafter,format_number(articles3,0), diff)
			msg=msg.replace(u" (+0)", u" (0)").replace(u" (-0)", u" (0)")
	elif proj.isalpha():
		middle= proj
		if sm.has_key(middle):
			before = str(int(ranking[middle])-1)
			after  = str(int(ranking[middle])+1)
			articles1 = articles2 = articles3 = 0
			if int(before) > 0:
				wikibefore = ranking_positions.get(before)
				site = Site(wikibefore, wlink.family())
				articles1 = site.get_articles()
				msg+= u"&t;%s&N;. &B;%s&N; %s" % (before, wikibefore, format_number(articles1,0))
			wikimiddle = middle
			site = Site(wikimiddle, wlink.family())
			articles2 = site.get_articles()
			diff = format_number(articles1 - articles2,0) if articles1 else ""
			diff = u" (+%s) | " % diff if diff else "" if not diff and not msg else " | "
			msg += u"%s&t;%s&N;. &B;%s&N; %s" % (diff, ranking[middle], wikimiddle, format_number(articles2,0))
			if int(after) <= len(sm):
				wikiafter=ranking_positions[after]
				site = Site(wikiafter, wlink.family())
				articles3 = site.get_articles()
				diff=format_number(articles2-articles3,0)
				diff = u" (-%s)" % diff if diff else ""
				msg += u" | &t;%s&N;. &B;%s&N; %s%s" %(after, wikiafter,format_number(articles3,0), diff)
			msg=msg.replace( u" (+0)", u" (0)").replace(" (-0)"," (0)")
		else: msg = u"%s does not exist." % wlink.sitename()
	msg += " || http://meta.wikimedia.org/wiki/%s" % wikiquote(metalink)
	return msg.replace(",",".")

def wikiranking(bot, evt, cmd):
	args = cmd.arguments or evt.lang
	wlink = WikiLink(args, evt.lang, evt.fam)
	fams = set(families.values())
	#fams.discard("wikiversity")
	if wlink.family() not in fams:
		fams = list(fams)
		bot.reply(evt, "Unknown family. Please choose on of these: %s" % join_list(fams))
		return True
	msg = ranking(args, wlink)
	if msg: bot.reply(evt, msg)
wikiranking.rule = "wrank"
wikiranking.aliases = ["wikirank",]
wikiranking.chanlang = {"ca": "lloc"}

def contest(bot, evt, cmd):
	data = net.pageWiki(u"Viquipèdia:Viquiconcurs")
	m=re.search("(?us)=== Edicions en curs ===.*edició (\d*)\|.*=== Edicions realitzades ===",data)
	if m:
		bot.reply(evt, "http://ca.wikipedia.org/wiki/Viquip%C3%A8dia:Viquiconcurs/edici%C3%B3_%s" % m.group(1))
	else:
		bot.reply(evt, "http://ca.wikipedia.org/wiki/Viquip%C3%A8dia:Viquiconcurs")
contest.rule = re.compile(ur"(viqui)?concurs")

def maintainance(bot, evt, cmd):
	epotime=int(time.time())-(86400*31)
	bot.reply(evt, "http://ca.wikipedia.org/wiki/Categoria:Viquip%C3%A8dia:Manteniment")
maintainance.rule = "maint"

def delete(bot, evt, cmd):
	bot.reply(evt, "http://ca.wikipedia.org/wiki/Categoria:Viquip%C3%A8dia:Elements_a_destruir")
delete.rule = "bor|esb(orra)?|dest"

def ws_requests(bot, evt, cmd):
	site = Site(evt.lang, evt.fam)
	bot.reply(evt, "http://%s/wiki/%s" % (site.sitename(), bot._translate(evt, "Wikipedia:Articles_for_deletion")))
ws_requests.rule = "deletion"
ws_requests.chanlang = {"ca": "propostes"}

def current_vandalism(bot, evt, cmd):
	bot.reply(evt, "http://ca.wikipedia.org/wiki/Viquip%C3%A8dia:Observatori_del_vandalisme")
current_vandalism.rule = ["vec","odv"]

def vandalism_watch(bot, evt, cmd):
	links = (
		"http://ca.wikipedia.org/wiki/Viquip%C3%A8dia:Observatori_del_vandalisme/Avisos_autom%C3%A0tics#footer",
		u"http://ca.wikipedia.org/wiki/Special:Contributions/%s" % wikiquote(cmd.arguments or "")
	)
	if not cmd.arguments: links=[links[0]]
	for link in links:
		bot.reply(evt, link)
vandalism_watch.rule = ["vnd", "vand"]

def ns(bot, evt, cmd):
	""".ns [<site> ]<number|namespace name>"""
	site = Site(evt.lang, evt.fam).load_namespaces()
	trg_site = WikiLink(cmd.dict["site"]).site() if cmd.dict["site"] else None
	trg_ns = cmd.dict['ns']
	#bot.reply(evt, "&B;site&N; %s &B;ns&N; %s", trg_site.sitename()if trg_site else "", trg_ns)
	if not trg_ns:
		bot.reply(evt, "namespace was expected.")
		return True
	if trg_site:
		trg_site.load_namespaces()

		if trg_ns.isdigit():
			ns_list = trg_site.namespaces_by_number()
			if ns_list.has_key(int(trg_ns)):
				bot.reply(evt, ns_list[int(trg_ns)][0])
			else:
				bot.reply(evt, ns_list)
		else:
			ns_list = site.namespaces_by_local_name()
			if ns_list.has_key(trg_ns):
				bot.reply(evt, encode(trg_site.namespaces_by_number()[ns_list[trg_ns]][0]))
			else:
				bot.reply(evt, "no such namespace")
	else:
		if trg_ns.isdigit():
			ns_list = site.namespaces_by_number()
			if ns_list.has_key(int(trg_ns)):
				bot.reply(evt, ns_list[int(trg_ns)][0])
			else:
				bot.reply(evt, ns_list)
		else:
			ns_list = site.namespaces_by_local_name()
			if ns_list.has_key(trg_ns):
				bot.reply(evt, ns_list[trg_ns])
ns.rule = re.compile("(?:$both)ns(?: (?P<site>[^:]+:))?(?: (?P<ns>\d+|[^:]+))")
ns.fullmsg = True

def links(bot, evt, cmd):
	c = cmd.dict['cmd']
	params = cmd.dict['params']
	reply=""
	site = Site(evt.lang, evt.fam)
	if c in ["b", "block"]:
		reply=u"http://%s/wiki/Special:Blockip/" % (site.sitename(), wikiquote(params))
	elif c in  ["cb", "bc"]:
		url = u"http://%s/wiki/Special:$sp$/%s" % (site.sitename(), wikiquote(params))
		reply=[]
		for l in c:
			if l == "c":
				reply.append(url.replace("$sp$","Contributions"))
			else:
				reply.append(url.replace("$sp$","BlockIP"))
		reply = " ".join(reply)
	elif cmd.startswith("mant"):
		epotime=int(time.time())-(86400*31)
		reply = [
			"http://%s/wiki/%s" % (site.sitename(), bot._translate(evt, "Categor%C3%ADa:Wikipedia:Mantenimiento", evt.lang)),
			u"http://%s/wiki/%s:%d_de_%s" %
				(
					site.sitename(),
					bot._translate(evt, "Categor%%C3%%ADa:Wikipedia:Mantenimiento", evt.lang),
					int(time.strftime("%d",time.localtime(epotime))),
					i_mes[int(time.strftime("%m",time.localtime(epotime)))]
				)
		]
		reply = " ".join(reply)
	elif cmd.startswith("dest") or cmd.startswith("bor"):
		reply="http://%s/wiki/%s"  % (
			site.sitename(),
			bot._translate(evt, "Categor%C3%ADa:Wikipedia:Borrar_%28definitivo%29", evt.lang)
		)
	elif cmd.startswith("vec"):
		reply="http://%s/wiki/%s"  % (
			site.sitename(),
			bot._translate(evt, "Wikipedia:Vandalismo_en_curso", evt.lang)
		)
	if reply:
		bot.reply(evt, reply)
links.rule = re.compile(r"(?i)^$trigger(?P<cmd>mant.*|dest.*|bor.*|vec.*|bc|cb|b|block|a[bd]|cad)(?: (?P<params>.*))?$")
#links.showas =["bc|cb", "b(lock)", "mant*", "dest*", "bor*", "vec*"]

def rc(bot, evt, cmd):
	""""""
	if evt.chan and not cmd.arguments:
		bot.pub_msg(evt, "irc://irc.wikimedia.org/%s.%s" % (evt.lang, evt.fam))
	elif cmd.arguments:
		site = WikiLink(cmd.arguments, evt.lang, evt.fam)
		channel = "#%s" % ".".join(site.sitename().split(".")[:-1])
		if cmd.opts['http']:
			link = "http://irc.lc/wikimedia/%s/User_@@@@@@@"
			channel = channel[1:]
		else:
			link = "irc://irc.wikimedia.org/%s"
		channel = "#%s" % ".".join(site.sitename().split(".")[:-1])
		if site.sitename() in ("translatewiki.net", "www.viquimedia.cat"):
			channel = "#betawiki-rc" if site.sitename().endswith(".net") else "#viquimedia"
			if cmd.opts['http']:
				link = "http://webchat.freenode.net/?channels=%s"
			else:
				link = "irc://chat.freenode.net/%s"
		bot.pub_msg(evt, link % (channel))
rc.rule = "rc"

def sitematrix__(bot, evt, cmd):
	import util.pywikilib as pywikilib
	for site in pywikilib._sitematrix:
		print site
sitematrix__.rule = "sm"

def create_lang_log(bot, evt, cmd):
	f = File("sitematrix_en.log")
	data = f.get()
	print data
	sm = [lang for lang in data if data[lang].has_key("families")]
	sm.sort()
	f = File("languages.log")
	f.put(sm, True)
	f.close()
create_lang_log.rule="cll"

def srv_time(bot, evt, cmd):
	bot_time = datetime.today()
	site = WikiLink(cmd.arguments or "", evt.lang, evt.fam).site()
	wiki_time = Time(site.get_api({"meta":"siteinfo","siprop":"general"})['query']['general']['time']).obj
	t = time_diff(bot_time, wiki_time)
	bot.reply(evt, "&B;&l;%s: &b;local time:&N; %s &B;server diff:&N; %i h %i m %i s" % (site.sitename(), time.strftime("%H:%M:%S"), t.hours, t.minutes, t.seconds))
srv_time.rule="time"
